<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    #video-play {
      display: flex;
      width: 100%;
      height: calc(100vh - 20px);
      /* padding-right: 10px; */
      box-sizing: border-box;
    }
    
    .video-list {
      flex: 0 0 120px;
      overflow: auto;
      padding: 4px;
      display: flex;
      flex-direction: column;
      overflow: hidden;
    }
    .list-content {
      flex: 1;
      overflow: auto;
    }
    .list-content::-webkit-scrollbar {
      width: 0;
    }
    .play-list {
      flex: 1;
      display: grid;
      grid-template-columns: 50% 50%;
      grid-template-rows: 50% 50%;
      color: #ccc;
      font-size: 14px;
      height: 100%;
    }
    .play-item {
      border: 1px solid #ccc;
      background-color: #000;
      display: flex;
      align-items: center;
      justify-content: center;
      position: relative;
    }
    .video-item {
      width: 100%;
      height: 100%;
    }
    .device-item {
      cursor: pointer;
      padding: 10px 0;
      font-size: 12px;
    }
    .active {
      background-color: #ecf5ff;
      color: #409eff;
    }
    .item-title {
      background-color: rgba(0, 0, 0, 0.3);
      position: absolute;
      top: 0;
      right: 0;
      /* width: 100%; */
      padding: 4px 10px;
      box-sizing: border-box;
      display: flex;
      justify-content: space-between;
      color: #409eff;
      align-items: center;
      font-weight: 700;
    }
    .video-title {
      cursor: pointer;
    }
    img {
      width: 16px;
      cursor: pointer;
      margin-left: 10px;
    }
  </style>
  <link href="../../css/index.css" rel="stylesheet">

</head>

<body>
  <div id="video-play">
    <div class="message" :class="message.type" v-if="message.text">{{message.text}}</div>
    <div class="video-list">
      <input class="search-list" v-model="videoSearch" style="width: 100%;" placeholder="路口" />
      <div class="list-content">
        <div v-for="item in searchList" :key="item.crossName">
          <div class="common-title video-title" @click="handlePlayAreaVideo(item)">{{item.crossName}}</div>
          <div
            v-for="child in item.devices" :key="child.ip"
            class="device-item"
            :class="activeItem(child) ? 'active' : ''"
            @click="handlePlayVideo(child)">
            {{child.name}}
          </div>
        </div>
      </div>
    </div>
    <div class="play-list">
      <div v-for="item in 4" class="play-item" :key="item" >
        <video class="video-item" :id="`videoId_${item - 1}`" v-show="playList[item - 1]" autoplay muted playsinline controls></video>
        <div class="item-title" v-if="playList[item - 1]">
          <div>{{playList[item - 1]?.name}}</div>
          <img src="../../assets/guanbi-write.png" @click="handleClose(item - 1)" />
        </div>
        <div v-else class="tip">点击列表播放视频</div>
      </div>
    </div>
  </div>
</body>
<script src="../../js/vue3.js"></script>
<script src="../../config.js"></script>
<script>
  const { createApp, ref, nextTick, reactive, onMounted, onUnmounted, watch, computed } = Vue
  const app = createApp({
    setup() {
      const videoList = ref([])

      // 加载视频列表
      const loadVideoList = () => {
        fetch('../../js/dict/videoList.json')
          .then(res => res.json())
          .then(res => {
            console.log('videoList', res);
            videoList.value = res
          })
      }

      const videoSearch = ref()

      // 根据路口搜索视频
      const searchList = computed(() => {
        return videoSearch.value ? videoList.value.filter(item => item.crossName.indexOf(videoSearch.value) > -1) : videoList.value
      })

      let pcObj = {
        videoId_1: null,
        videoId_2: null,
        videoId_3: null,
        videoId_4: null
      }
      // 开始播放视频
      const startPlay = (id, url) => {
        const videoEl = document.getElementById(id)
        console.log('videoEl', videoEl);
        if (!videoEl) { return }
        pcObj[id] = new RTCPeerConnection({
          // sdpSemantics: 'unified-plan'
        })
        pcObj[id].ontrack = function (event) {
          console.log(event.streams.length + ' track is delivered')
          videoEl.srcObject = event.streams[0]
          videoEl.play()
        }
        pcObj[id].addTransceiver('video', { direction: 'sendrecv' })
        pcObj[id].onnegotiationneeded = async function handleNegotiationNeeded() {
          const offer = await pcObj[id].createOffer()

          await pcObj[id].setLocalDescription(offer)
          const formData = new FormData()
          formData.append('data', btoa(pcObj[id].localDescription.sdp))
          fetch(videoUrl + 'api/video/stream/' + url + '/channel/0/webrtc', {
            method: 'POST',
            body: formData,
          })
          .then(res => res.text())
          .then((res) => {
            try {
              pcObj[id].setRemoteDescription(
                new RTCSessionDescription({ type: 'answer', sdp: window.atob(res) })
              )
            } catch (e) {
              console.warn(e)
            }
          }).catch((e) => {
            console.log('ee', e)
            message.text = '无法播放视频'
            message.type = MESSAGE_TYPE.ERROR
            // errTip.value = '无法播放视频'
          })
        }

        const dc = pcObj[id].createDataChannel('rtsptowebSendChannel')
        dc.onopen = (event) => {
          console.log(`${dc.label} has opened`)
          dc.send('ping')
        }
        dc.onclose = (event) => {
          console.log(`${dc.label} has closed`)
          startPlay(id, url)
        }
        dc.onmessage = (event) => console.log(event.data)
      }

      // 关闭视频
      const close = (id) => {
        pcObj[id] && pcObj[id]?.close()
        pcObj[id] = null
        // errTip.value = ''
      }

      // 关闭全部视频
      const closeAll = () => {
        playList.value.forEach((item, index) => {
          close(`videoId_${playList.value.length - 1}`)
        })
      }

      // 是否激活栏
      const activeItem = computed(() => {
        return (item) => {
          const result = playList.value.find(ele => ele.ip === item.ip)
          return result
        }
      })

      const playList = ref(['', '', '', ''])

      // 点击视频播放
      const handlePlayVideo = (child) => {
        // 如果视频已经在列表里面，那么就是取消播放
        const resultIndex = playList.value.findIndex(item => item.ip === child.ip)        
        if (resultIndex !== -1) {
          playList.value[resultIndex] = ''
          close(resultIndex)
          return
        }
        // 如果有冗余的位置进行播放，那么就占用那个位置
        const index = playList.value.findIndex(item => !item)
        
        if(index === -1) {
          message.text = '最多可播放四个视频'
          message.type = MESSAGE_TYPE.ALERT
          return
        }
        console.log('index', index);
        
        playList.value[index] = child        
        startPlay(`videoId_${index}`, child.ip)
      }

      // 点击路口播放当前路口所有视频
      const handlePlayAreaVideo = (item) => {
        playList.value = ['', '', '', '']
        item.devices.forEach(ele => {
          handlePlayVideo(ele)
        })
        
      }
      
      const MESSAGE_TYPE = {
        'SUCCESS': 'success',
        'INFO': 'info',
        'ALERT': 'alert',
        'ERROR': 'error'
      }

      const message = reactive({
        type: '',
        text: ''
      })

      // 弹窗消息1.5秒消失
      watch(
        () => message.text,
        () => {
          if(message.text) {
            setTimeout(() => {
              message.text = ''
            }, 2000)
          }
        }
      )

      // 点击视频名称 关闭视频
      const handleClose = (index) => {
        playList.value[index] = ''
        close(index)
      }

      onMounted(() => {
        loadVideoList()
      })

      onUnmounted(() => {
        closeAll()
      })
      return {
        videoList,
        videoSearch,
        searchList,
        playList,
        activeItem,
        message,
        handlePlayVideo,
        handleClose,
        handlePlayAreaVideo
      }
    },
  })
  app.mount('#video-play')
</script>

</html>